package lco.generator;

import java.util.Iterator;
import lco.cRLanguage.Add;
import lco.cRLanguage.Assignment;
import lco.cRLanguage.AssignmentRightHand;
import lco.cRLanguage.CalcCR;
import lco.cRLanguage.CalcMean;
import lco.cRLanguage.Callable;
import lco.cRLanguage.Declaration;
import lco.cRLanguage.Delete;
import lco.cRLanguage.File;
import lco.cRLanguage.FindSimilar;
import lco.cRLanguage.For;
import lco.cRLanguage.ForAll;
import lco.cRLanguage.ForFile;
import lco.cRLanguage.ForJava;
import lco.cRLanguage.ForWhile;
import lco.cRLanguage.HighestCR;
import lco.cRLanguage.IndexedVariable;
import lco.cRLanguage.IndexedVectorial;
import lco.cRLanguage.IntegerExpression;
import lco.cRLanguage.Method;
import lco.cRLanguage.NumericFunctionExpression;
import lco.cRLanguage.Print;
import lco.cRLanguage.Program;
import lco.cRLanguage.ScalarAssign;
import lco.cRLanguage.ScalarDeclaration;
import lco.cRLanguage.ScalarVariable;
import lco.cRLanguage.Size;
import lco.cRLanguage.Statement;
import lco.cRLanguage.StringValue;
import lco.cRLanguage.Variable;
import lco.cRLanguage.VectorialAssign;
import lco.cRLanguage.VectorialDeclaration;
import lco.cRLanguage.VectorialVariable;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.xbase.lib.BooleanExtensions;
import org.eclipse.xtext.xbase.lib.ComparableExtensions;
import org.eclipse.xtext.xbase.lib.IntegerExtensions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.eclipse.xtext.xtend2.lib.StringConcatenation;

@SuppressWarnings("all")
public class CRLanguageGenerator implements IGenerator {
  
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
    {
      String _className = this.className(resource);
      String _operator_plus = StringExtensions.operator_plus(_className, ".py");
      EList<EObject> _contents = resource.getContents();
      EObject _head = IterableExtensions.<EObject>head(_contents);
      String _awesomePythonCode = this.toAwesomePythonCode(((Program) _head));
      fsa.generateFile(_operator_plus, _awesomePythonCode);
      StringConcatenation _generateAwesomePythonFramework = this.generateAwesomePythonFramework();
      fsa.generateFile("cr.py", _generateAwesomePythonFramework);
    }
  }
  
  public String className(final Resource res) {
    {
      URI _uRI = res.getURI();
      String _lastSegment = _uRI.lastSegment();
      String name = _lastSegment;
      int _lastIndexOf = name.lastIndexOf(".");
      String _substring = name.substring(0, _lastIndexOf);
      return _substring;
    }
  }
  
  public Object generateNumericFunctionExpression(final NumericFunctionExpression nfe) {
    CharSequence _xifexpression = null;
    IndexedVariable _indexedVariable = nfe.getIndexedVariable();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_indexedVariable, null);
    if (_operator_notEquals) {
      IndexedVariable _indexedVariable_1 = nfe.getIndexedVariable();
      String _generateIndexedVariable = this.generateIndexedVariable(_indexedVariable_1);
      return _generateIndexedVariable;
    } else {
      CharSequence _xifexpression_1 = null;
      Callable _callable = nfe.getCallable();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_callable, null);
      if (_operator_notEquals_1) {
        Callable _callable_1 = nfe.getCallable();
        String _generateCallable = this.generateCallable(_callable_1);
        return _generateCallable;
      } else {
        CharSequence _xifexpression_2 = null;
        String _double = nfe.getDouble();
        boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_double, null);
        if (_operator_notEquals_2) {
          StringConcatenation _builder = new StringConcatenation();
          String _double_1 = nfe.getDouble();
          _builder.append(_double_1, "");
          return _builder;
        } else {
          CharSequence _xifexpression_3 = null;
          int _int = nfe.getInt();
          boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(((Integer)_int), null);
          if (_operator_notEquals_3) {
            StringConcatenation _builder_1 = new StringConcatenation();
            int _int_1 = nfe.getInt();
            _builder_1.append(_int_1, "");
            return _builder_1;
          }
          _xifexpression_2 = _xifexpression_3;
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public Object generateStringValue(final StringValue sv) {
    Object _xifexpression = null;
    NumericFunctionExpression _variableArg = sv.getVariableArg();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_variableArg, null);
    if (_operator_notEquals) {
      NumericFunctionExpression _variableArg_1 = sv.getVariableArg();
      Object _generateNumericFunctionExpression = this.generateNumericFunctionExpression(_variableArg_1);
      return _generateNumericFunctionExpression;
    } else {
      Object _xifexpression_1 = null;
      String _stringArg = sv.getStringArg();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_stringArg, null);
      if (_operator_notEquals_1) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("\"");
        String _stringArg_1 = sv.getStringArg();
        String _replace = _stringArg_1.replace("\t", "\\t");
        String _replace_1 = _replace.replace("\n", "\\n");
        _builder.append(_replace_1, "");
        _builder.append("\"");
        return _builder;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public String generateIndexedVariable(final IndexedVariable iv) {
    {
      String expr = "";
      Variable _variable = iv.getVariable();
      String _generateVariable = this.generateVariable(_variable);
      String _operator_plus = StringExtensions.operator_plus(expr, _generateVariable);
      expr = _operator_plus;
      IntegerExpression _x = iv.getX();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_x, null);
      if (_operator_notEquals) {
        {
          String _operator_plus_1 = StringExtensions.operator_plus(expr, "[");
          IntegerExpression _x_1 = iv.getX();
          Object _generateIntegerExpression = this.generateIntegerExpression(_x_1);
          String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, _generateIntegerExpression);
          String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, "]");
          expr = _operator_plus_3;
          IntegerExpression _y = iv.getY();
          boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_y, null);
          if (_operator_notEquals_1) {
            String _operator_plus_4 = StringExtensions.operator_plus(expr, "[");
            IntegerExpression _y_1 = iv.getY();
            Object _generateIntegerExpression_1 = this.generateIntegerExpression(_y_1);
            String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, _generateIntegerExpression_1);
            String _operator_plus_6 = StringExtensions.operator_plus(_operator_plus_5, "]");
            expr = _operator_plus_6;
          }
        }
      }
      return expr;
    }
  }
  
  public String generateIndexedVectorial(final IndexedVectorial iv) {
    {
      String expr = "";
      VectorialVariable _variable = iv.getVariable();
      String _generateVariable = this.generateVariable(_variable);
      String _operator_plus = StringExtensions.operator_plus(expr, _generateVariable);
      expr = _operator_plus;
      IntegerExpression _x = iv.getX();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_x, null);
      if (_operator_notEquals) {
        {
          String _operator_plus_1 = StringExtensions.operator_plus(expr, "[");
          IntegerExpression _x_1 = iv.getX();
          Object _generateIntegerExpression = this.generateIntegerExpression(_x_1);
          String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, _generateIntegerExpression);
          String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, "]");
          expr = _operator_plus_3;
          IntegerExpression _y = iv.getY();
          boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_y, null);
          if (_operator_notEquals_1) {
            String _operator_plus_4 = StringExtensions.operator_plus(expr, "[");
            IntegerExpression _y_1 = iv.getY();
            Object _generateIntegerExpression_1 = this.generateIntegerExpression(_y_1);
            String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, _generateIntegerExpression_1);
            String _operator_plus_6 = StringExtensions.operator_plus(_operator_plus_5, "]");
            expr = _operator_plus_6;
          }
        }
      }
      return expr;
    }
  }
  
  public String generatePrint(final Print p) {
    String _xblockexpression = null;
    {
      String expr = "print_(";
      EList<StringValue> _args = p.getArgs();
      for (final StringValue sv : _args) {
        Object _generateStringValue = this.generateStringValue(sv);
        String _operator_plus = StringExtensions.operator_plus(expr, _generateStringValue);
        String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ", ");
        expr = _operator_plus_1;
      }
      int _length = expr.length();
      int _operator_minus = IntegerExtensions.operator_minus(((Integer)_length), ((Integer)2));
      String _substring = expr.substring(0, _operator_minus);
      expr = _substring;
      String _operator_plus_2 = StringExtensions.operator_plus(expr, ")");
      String _expr = expr = _operator_plus_2;
      _xblockexpression = (_expr);
    }
    return _xblockexpression;
  }
  
  public String toAwesomePythonCode(final Program p) {
    {
      String imports = "from os import listdir\n";
      String _operator_plus = StringExtensions.operator_plus(imports, "from cr import *\n\n");
      imports = _operator_plus;
      EList<Declaration> _declarations = p.getDeclarations();
      String _generateDeclarations = this.generateDeclarations(_declarations);
      String declarations = _generateDeclarations;
      EList<Statement> _statements = p.getStatements();
      String _generateStatements = this.generateStatements(_statements);
      String statements = _generateStatements;
      String _operator_plus_1 = StringExtensions.operator_plus(imports, declarations);
      String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, statements);
      return _operator_plus_2;
    }
  }
  
  public String generateDeclarations(final EList<Declaration> declarations) {
    {
      String generatedDeclarations = "";
      for (final Declaration d : declarations) {
        {
          String currentDeclaration = "";
          ScalarDeclaration _sd = d.getSd();
          boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_sd, null);
          if (_operator_notEquals) {
            {
              StringConcatenation _builder = new StringConcatenation();
              ScalarDeclaration _sd_1 = d.getSd();
              ScalarVariable _variable = _sd_1.getVariable();
              String _name = _variable.getName();
              _builder.append(_name, "");
              String _string = _builder.toString();
              String _operator_plus = StringExtensions.operator_plus(_string, " = ");
              currentDeclaration = _operator_plus;
              ScalarDeclaration _sd_2 = d.getSd();
              String _type = _sd_2.getType();
              boolean _operator_equals = ObjectExtensions.operator_equals(_type, "Int");
              if (_operator_equals) {
                ScalarDeclaration _sd_3 = d.getSd();
                AssignmentRightHand _expr = _sd_3.getExpr();
                boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_expr, null);
                if (_operator_notEquals_1) {
                  StringConcatenation _builder_1 = new StringConcatenation();
                  ScalarDeclaration _sd_4 = d.getSd();
                  AssignmentRightHand _expr_1 = _sd_4.getExpr();
                  int _integer = _expr_1.getInteger();
                  _builder_1.append(_integer, "");
                  String _operator_plus_1 = StringExtensions.operator_plus(currentDeclaration, _builder_1);
                  currentDeclaration = _operator_plus_1;
                } else {
                  String _operator_plus_2 = StringExtensions.operator_plus(currentDeclaration, "0");
                  currentDeclaration = _operator_plus_2;
                }
              } else {
                ScalarDeclaration _sd_5 = d.getSd();
                String _type_1 = _sd_5.getType();
                boolean _operator_equals_1 = ObjectExtensions.operator_equals(_type_1, "Real");
                if (_operator_equals_1) {
                  ScalarDeclaration _sd_6 = d.getSd();
                  AssignmentRightHand _expr_2 = _sd_6.getExpr();
                  boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_expr_2, null);
                  if (_operator_notEquals_2) {
                    StringConcatenation _builder_2 = new StringConcatenation();
                    ScalarDeclaration _sd_7 = d.getSd();
                    AssignmentRightHand _expr_3 = _sd_7.getExpr();
                    String _double = _expr_3.getDouble();
                    _builder_2.append(_double, "");
                    String _operator_plus_3 = StringExtensions.operator_plus(currentDeclaration, _builder_2);
                    currentDeclaration = _operator_plus_3;
                  } else {
                    String _operator_plus_4 = StringExtensions.operator_plus(currentDeclaration, "0.0");
                    currentDeclaration = _operator_plus_4;
                  }
                } else {
                  ScalarDeclaration _sd_8 = d.getSd();
                  String _type_2 = _sd_8.getType();
                  boolean _operator_equals_2 = ObjectExtensions.operator_equals(_type_2, "Partition");
                  if (_operator_equals_2) {
                    ScalarDeclaration _sd_9 = d.getSd();
                    AssignmentRightHand _expr_4 = _sd_9.getExpr();
                    boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_expr_4, null);
                    if (_operator_notEquals_3) {
                      String _operator_plus_5 = StringExtensions.operator_plus(currentDeclaration, "Partition(\"");
                      StringConcatenation _builder_3 = new StringConcatenation();
                      ScalarDeclaration _sd_10 = d.getSd();
                      AssignmentRightHand _expr_5 = _sd_10.getExpr();
                      File _file = _expr_5.getFile();
                      String _file_1 = _file.getFile();
                      _builder_3.append(_file_1, "");
                      String _operator_plus_6 = StringExtensions.operator_plus(_operator_plus_5, _builder_3);
                      String _operator_plus_7 = StringExtensions.operator_plus(_operator_plus_6, "\")");
                      currentDeclaration = _operator_plus_7;
                    } else {
                      String _operator_plus_8 = StringExtensions.operator_plus(currentDeclaration, "None");
                      currentDeclaration = _operator_plus_8;
                    }
                  }
                }
              }
            }
          } else {
            boolean _operator_and = false;
            VectorialDeclaration _vd = d.getVd();
            int _y = _vd.getY();
            boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(((Integer)_y), null);
            if (!_operator_notEquals_4) {
              _operator_and = false;
            } else {
              VectorialDeclaration _vd_1 = d.getVd();
              int _y_1 = _vd_1.getY();
              boolean _operator_notEquals_5 = ObjectExtensions.operator_notEquals(((Integer)_y_1), ((Integer)0));
              _operator_and = BooleanExtensions.operator_and(_operator_notEquals_4, _operator_notEquals_5);
            }
            if (_operator_and) {
              StringConcatenation _builder_4 = new StringConcatenation();
              VectorialDeclaration _vd_2 = d.getVd();
              VectorialVariable _variable_1 = _vd_2.getVariable();
              String _name_1 = _variable_1.getName();
              _builder_4.append(_name_1, "");
              String _string_1 = _builder_4.toString();
              String _operator_plus_9 = StringExtensions.operator_plus(_string_1, " = Matrix(");
              VectorialDeclaration _vd_3 = d.getVd();
              int _x = _vd_3.getX();
              String _operator_plus_10 = StringExtensions.operator_plus(_operator_plus_9, ((Integer)_x));
              String _operator_plus_11 = StringExtensions.operator_plus(_operator_plus_10, ", ");
              VectorialDeclaration _vd_4 = d.getVd();
              int _y_2 = _vd_4.getY();
              String _operator_plus_12 = StringExtensions.operator_plus(_operator_plus_11, ((Integer)_y_2));
              String _operator_plus_13 = StringExtensions.operator_plus(_operator_plus_12, ")");
              currentDeclaration = _operator_plus_13;
            } else {
              StringConcatenation _builder_5 = new StringConcatenation();
              VectorialDeclaration _vd_5 = d.getVd();
              VectorialVariable _variable_2 = _vd_5.getVariable();
              String _name_2 = _variable_2.getName();
              _builder_5.append(_name_2, "");
              String _string_2 = _builder_5.toString();
              String _operator_plus_14 = StringExtensions.operator_plus(_string_2, " = Array(");
              VectorialDeclaration _vd_6 = d.getVd();
              int _x_1 = _vd_6.getX();
              String _operator_plus_15 = StringExtensions.operator_plus(_operator_plus_14, ((Integer)_x_1));
              String _operator_plus_16 = StringExtensions.operator_plus(_operator_plus_15, ")");
              currentDeclaration = _operator_plus_16;
            }
          }
          String _operator_plus_17 = StringExtensions.operator_plus(generatedDeclarations, currentDeclaration);
          String _operator_plus_18 = StringExtensions.operator_plus(_operator_plus_17, "\n");
          generatedDeclarations = _operator_plus_18;
        }
      }
      return generatedDeclarations;
    }
  }
  
  public String generateStatements(final EList<Statement> statements) {
    {
      String generatedStatements = "";
      for (final Statement s : statements) {
        Assignment _a = s.getA();
        boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_a, null);
        if (_operator_notEquals) {
          Assignment _a_1 = s.getA();
          String _generateAssignment = this.generateAssignment(_a_1);
          String _operator_plus = StringExtensions.operator_plus(generatedStatements, _generateAssignment);
          String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, "\n");
          generatedStatements = _operator_plus_1;
        } else {
          Callable _c = s.getC();
          boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_c, null);
          if (_operator_notEquals_1) {
            Callable _c_1 = s.getC();
            String _generateCallable = this.generateCallable(_c_1);
            String _operator_plus_2 = StringExtensions.operator_plus(generatedStatements, _generateCallable);
            String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, "\n");
            generatedStatements = _operator_plus_3;
          } else {
            Print _p = s.getP();
            boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_p, null);
            if (_operator_notEquals_2) {
              Print _p_1 = s.getP();
              String _generatePrint = this.generatePrint(_p_1);
              String _operator_plus_4 = StringExtensions.operator_plus(generatedStatements, _generatePrint);
              String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, "\n");
              generatedStatements = _operator_plus_5;
            } else {
              For _f = s.getF();
              boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_f, null);
              if (_operator_notEquals_3) {
                For _f_1 = s.getF();
                String _generateFor = this.generateFor(_f_1);
                String _operator_plus_6 = StringExtensions.operator_plus(generatedStatements, _generateFor);
                String _operator_plus_7 = StringExtensions.operator_plus(_operator_plus_6, "\n");
                generatedStatements = _operator_plus_7;
              }
            }
          }
        }
      }
      return generatedStatements;
    }
  }
  
  public String generateAssignment(final Assignment a) {
    {
      String assignment = "";
      ScalarAssign _sa = a.getSa();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_sa, null);
      if (_operator_notEquals) {
        ScalarAssign _sa_1 = a.getSa();
        Variable _var = _sa_1.getVar();
        String _generateVariable = this.generateVariable(_var);
        String _operator_plus = StringExtensions.operator_plus(assignment, _generateVariable);
        String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, " = ");
        ScalarAssign _sa_2 = a.getSa();
        AssignmentRightHand _expr = _sa_2.getExpr();
        Object _generateAssignmentRightHand = this.generateAssignmentRightHand(_expr);
        String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, _generateAssignmentRightHand);
        assignment = _operator_plus_2;
      } else {
        VectorialAssign _va = a.getVa();
        boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_va, null);
        if (_operator_notEquals_1) {
          VectorialAssign _va_1 = a.getVa();
          IndexedVectorial _var_1 = _va_1.getVar();
          String _generateIndexedVectorial = this.generateIndexedVectorial(_var_1);
          String _operator_plus_3 = StringExtensions.operator_plus(assignment, _generateIndexedVectorial);
          String _operator_plus_4 = StringExtensions.operator_plus(_operator_plus_3, " = ");
          VectorialAssign _va_2 = a.getVa();
          AssignmentRightHand _expr_1 = _va_2.getExpr();
          Object _generateAssignmentRightHand_1 = this.generateAssignmentRightHand(_expr_1);
          String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, _generateAssignmentRightHand_1);
          assignment = _operator_plus_5;
        }
      }
      return assignment;
    }
  }
  
  public Object generateAssignmentRightHand(final AssignmentRightHand arh) {
    CharSequence _xifexpression = null;
    File _file = arh.getFile();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_file, null);
    if (_operator_notEquals) {
      File _file_1 = arh.getFile();
      StringConcatenation _generateFile = this.generateFile(_file_1);
      return _generateFile;
    } else {
      CharSequence _xifexpression_1 = null;
      Variable _variable = arh.getVariable();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_variable, null);
      if (_operator_notEquals_1) {
        Variable _variable_1 = arh.getVariable();
        String _generateVariable = this.generateVariable(_variable_1);
        return _generateVariable;
      } else {
        CharSequence _xifexpression_2 = null;
        IndexedVectorial _indexedVectorial = arh.getIndexedVectorial();
        boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_indexedVectorial, null);
        if (_operator_notEquals_2) {
          IndexedVectorial _indexedVectorial_1 = arh.getIndexedVectorial();
          String _generateIndexedVectorial = this.generateIndexedVectorial(_indexedVectorial_1);
          return _generateIndexedVectorial;
        } else {
          CharSequence _xifexpression_3 = null;
          Callable _callable = arh.getCallable();
          boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_callable, null);
          if (_operator_notEquals_3) {
            Callable _callable_1 = arh.getCallable();
            String _generateCallable = this.generateCallable(_callable_1);
            return _generateCallable;
          } else {
            CharSequence _xifexpression_4 = null;
            String _double = arh.getDouble();
            boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(_double, null);
            if (_operator_notEquals_4) {
              StringConcatenation _builder = new StringConcatenation();
              String _double_1 = arh.getDouble();
              _builder.append(_double_1, "");
              return _builder;
            } else {
              CharSequence _xifexpression_5 = null;
              int _integer = arh.getInteger();
              boolean _operator_notEquals_5 = ObjectExtensions.operator_notEquals(((Integer)_integer), null);
              if (_operator_notEquals_5) {
                StringConcatenation _builder_1 = new StringConcatenation();
                int _integer_1 = arh.getInteger();
                _builder_1.append(_integer_1, "");
                return _builder_1;
              }
              _xifexpression_4 = _xifexpression_5;
            }
            _xifexpression_3 = _xifexpression_4;
          }
          _xifexpression_2 = _xifexpression_3;
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public StringConcatenation generateFile(final File f) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("Partition(\"");
    String _file = f.getFile();
    _builder.append(_file, "");
    _builder.append("\")");
    return _builder;
  }
  
  public String generateVariable(final Variable v) {
    String _xifexpression = null;
    EClass _eClass = v.eClass();
    String _name = _eClass.getName();
    boolean _equals = _name.equals("ScalarVariable");
    if (_equals) {
      StringConcatenation _builder = new StringConcatenation();
      String _name_1 = v.getName();
      _builder.append(_name_1, "");
      String _string = _builder.toString();
      return _string;
    } else {
      String _xifexpression_1 = null;
      EClass _eClass_1 = v.eClass();
      String _name_2 = _eClass_1.getName();
      boolean _equals_1 = _name_2.equals("VectorialVariable");
      if (_equals_1) {
        StringConcatenation _builder_1 = new StringConcatenation();
        String _name_3 = v.getName();
        _builder_1.append(_name_3, "");
        String _string_1 = _builder_1.toString();
        return _string_1;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public Object generateIntegerExpression(final IntegerExpression ie) {
    CharSequence _xifexpression = null;
    Variable _variable = ie.getVariable();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_variable, null);
    if (_operator_notEquals) {
      Variable _variable_1 = ie.getVariable();
      String _generateVariable = this.generateVariable(_variable_1);
      return _generateVariable;
    } else {
      CharSequence _xifexpression_1 = null;
      int _int = ie.getInt();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(((Integer)_int), null);
      if (_operator_notEquals_1) {
        StringConcatenation _builder = new StringConcatenation();
        int _int_1 = ie.getInt();
        _builder.append(_int_1, "");
        return _builder;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public String generateCallable(final Callable c) {
    String _xifexpression = null;
    CalcCR _cr = c.getCr();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_cr, null);
    if (_operator_notEquals) {
      CalcCR _cr_1 = c.getCr();
      String _generateCalcCR = this.generateCalcCR(_cr_1);
      return _generateCalcCR;
    } else {
      String _xifexpression_1 = null;
      CalcMean _mean = c.getMean();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_mean, null);
      if (_operator_notEquals_1) {
        CalcMean _mean_1 = c.getMean();
        String _generateCalcMean = this.generateCalcMean(_mean_1);
        return _generateCalcMean;
      } else {
        String _xifexpression_2 = null;
        HighestCR _highest = c.getHighest();
        boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_highest, null);
        if (_operator_notEquals_2) {
          HighestCR _highest_1 = c.getHighest();
          String _generateHighestCR = this.generateHighestCR(_highest_1);
          return _generateHighestCR;
        } else {
          String _xifexpression_3 = null;
          FindSimilar _similar = c.getSimilar();
          boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_similar, null);
          if (_operator_notEquals_3) {
            FindSimilar _similar_1 = c.getSimilar();
            String _generateFindSimilar = this.generateFindSimilar(_similar_1);
            return _generateFindSimilar;
          } else {
            String _xifexpression_4 = null;
            Method _method = c.getMethod();
            boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(_method, null);
            if (_operator_notEquals_4) {
              Method _method_1 = c.getMethod();
              String _generateMethod = this.generateMethod(_method_1);
              return _generateMethod;
            }
            _xifexpression_3 = _xifexpression_4;
          }
          _xifexpression_2 = _xifexpression_3;
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public String generateCalcCR(final CalcCR cc) {
    {
      IndexedVariable _arg1 = cc.getArg1();
      String _generateIndexedVariable = this.generateIndexedVariable(_arg1);
      String _operator_plus = StringExtensions.operator_plus("calcCR(", _generateIndexedVariable);
      String expr = _operator_plus;
      IndexedVariable _arg2 = cc.getArg2();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_arg2, null);
      if (_operator_notEquals) {
        String _operator_plus_1 = StringExtensions.operator_plus(expr, ", ");
        IndexedVariable _arg2_1 = cc.getArg2();
        String _generateIndexedVariable_1 = this.generateIndexedVariable(_arg2_1);
        String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, _generateIndexedVariable_1);
        expr = _operator_plus_2;
      }
      String _operator_plus_3 = StringExtensions.operator_plus(expr, ")");
      expr = _operator_plus_3;
      return expr;
    }
  }
  
  public String generateCalcMean(final CalcMean cm) {
    {
      IndexedVariable _arg = cm.getArg();
      String _generateIndexedVariable = this.generateIndexedVariable(_arg);
      String _operator_plus = StringExtensions.operator_plus("calcMean(", _generateIndexedVariable);
      String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ")");
      String expr = _operator_plus_1;
      return expr;
    }
  }
  
  public String generateHighestCR(final HighestCR hc) {
    {
      IndexedVariable _arg = hc.getArg();
      String _generateIndexedVariable = this.generateIndexedVariable(_arg);
      String _operator_plus = StringExtensions.operator_plus("highestCR(", _generateIndexedVariable);
      String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ")");
      String expr = _operator_plus_1;
      return expr;
    }
  }
  
  public String generateFindSimilar(final FindSimilar fs) {
    {
      IndexedVariable _arg1 = fs.getArg1();
      String _generateIndexedVariable = this.generateIndexedVariable(_arg1);
      String _operator_plus = StringExtensions.operator_plus("findSimilar(", _generateIndexedVariable);
      String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ", ");
      String expr = _operator_plus_1;
      NumericFunctionExpression _arg2 = fs.getArg2();
      Object _generateNumericFunctionExpression = this.generateNumericFunctionExpression(_arg2);
      String _operator_plus_2 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression);
      String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, ", ");
      expr = _operator_plus_3;
      NumericFunctionExpression _arg3 = fs.getArg3();
      Object _generateNumericFunctionExpression_1 = this.generateNumericFunctionExpression(_arg3);
      String _operator_plus_4 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression_1);
      String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, ")");
      expr = _operator_plus_5;
      return expr;
    }
  }
  
  public String generateMethod(final Method m) {
    String _xifexpression = null;
    Size _size = m.getSize();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_size, null);
    if (_operator_notEquals) {
      Size _size_1 = m.getSize();
      String _generateSizeMethod = this.generateSizeMethod(_size_1);
      return _generateSizeMethod;
    } else {
      String _xifexpression_1 = null;
      Add _add = m.getAdd();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_add, null);
      if (_operator_notEquals_1) {
        Add _add_1 = m.getAdd();
        String _generateAddMethod = this.generateAddMethod(_add_1);
        return _generateAddMethod;
      } else {
        String _xifexpression_2 = null;
        Delete _delete = m.getDelete();
        boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_delete, null);
        if (_operator_notEquals_2) {
          Delete _delete_1 = m.getDelete();
          String _generateDeleteMethod = this.generateDeleteMethod(_delete_1);
          return _generateDeleteMethod;
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  public String generateSizeMethod(final Size s) {
    {
      IndexedVariable _variable = s.getVariable();
      String _generateIndexedVariable = this.generateIndexedVariable(_variable);
      String _operator_plus = StringExtensions.operator_plus(_generateIndexedVariable, ".size()");
      String expr = _operator_plus;
      return expr;
    }
  }
  
  public String generateAddMethod(final Add a) {
    {
      IndexedVariable _variable = a.getVariable();
      String _generateIndexedVariable = this.generateIndexedVariable(_variable);
      String _operator_plus = StringExtensions.operator_plus(_generateIndexedVariable, ".add(");
      String expr = _operator_plus;
      EList<NumericFunctionExpression> _args = a.getArgs();
      Iterator<NumericFunctionExpression> _iterator = _args.iterator();
      Iterator<NumericFunctionExpression> iter = _iterator;
      boolean _hasNext = iter.hasNext();
      Boolean _xwhileexpression = _hasNext;
      while (_xwhileexpression) {
        {
          NumericFunctionExpression _next = iter.next();
          Object _generateNumericFunctionExpression = this.generateNumericFunctionExpression(_next);
          String _operator_plus_1 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression);
          expr = _operator_plus_1;
          boolean _hasNext_1 = iter.hasNext();
          if (_hasNext_1) {
            String _operator_plus_2 = StringExtensions.operator_plus(expr, ", ");
            expr = _operator_plus_2;
          }
        }
        boolean _hasNext_2 = iter.hasNext();
        _xwhileexpression = _hasNext_2;
      }
      String _operator_plus_3 = StringExtensions.operator_plus(expr, ")");
      expr = _operator_plus_3;
      return expr;
    }
  }
  
  public String generateDeleteMethod(final Delete d) {
    {
      IndexedVariable _variable = d.getVariable();
      String _generateIndexedVariable = this.generateIndexedVariable(_variable);
      String _operator_plus = StringExtensions.operator_plus(_generateIndexedVariable, ".delete(");
      String expr = _operator_plus;
      boolean _operator_and = false;
      EList<NumericFunctionExpression> _dely = d.getDely();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_dely, null);
      if (!_operator_notEquals) {
        _operator_and = false;
      } else {
        EList<NumericFunctionExpression> _dely_1 = d.getDely();
        int _size = _dely_1.size();
        boolean _operator_greaterThan = ComparableExtensions.<Integer>operator_greaterThan(((Integer)_size), ((Integer)0));
        _operator_and = BooleanExtensions.operator_and(_operator_notEquals, _operator_greaterThan);
      }
      boolean isMatrix = _operator_and;
      Callable _function = d.getFunction();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_function, null);
      if (_operator_notEquals_1) {
        String _operator_plus_1 = StringExtensions.operator_plus(expr, "*");
        Callable _function_1 = d.getFunction();
        String _generateCallable = this.generateCallable(_function_1);
        String _operator_plus_2 = StringExtensions.operator_plus(_operator_plus_1, _generateCallable);
        expr = _operator_plus_2;
      } else {
        {
          EList<NumericFunctionExpression> _delx = d.getDelx();
          Iterator<NumericFunctionExpression> _iterator = _delx.iterator();
          Iterator<NumericFunctionExpression> iterX = _iterator;
          Iterator<NumericFunctionExpression> iterY = null;
          if (isMatrix) {
            EList<NumericFunctionExpression> _dely_2 = d.getDely();
            Iterator<NumericFunctionExpression> _iterator_1 = _dely_2.iterator();
            iterY = _iterator_1;
          }
          boolean _hasNext = iterX.hasNext();
          Boolean _xwhileexpression = _hasNext;
          while (_xwhileexpression) {
            {
              String _operator_plus_3 = StringExtensions.operator_plus(expr, "[");
              expr = _operator_plus_3;
              NumericFunctionExpression _next = iterX.next();
              Object _generateNumericFunctionExpression = this.generateNumericFunctionExpression(_next);
              String _operator_plus_4 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression);
              expr = _operator_plus_4;
              if (isMatrix) {
                String _operator_plus_5 = StringExtensions.operator_plus(expr, ", ");
                NumericFunctionExpression _next_1 = iterY.next();
                Object _generateNumericFunctionExpression_1 = this.generateNumericFunctionExpression(_next_1);
                String _operator_plus_6 = StringExtensions.operator_plus(_operator_plus_5, _generateNumericFunctionExpression_1);
                expr = _operator_plus_6;
              }
              String _operator_plus_7 = StringExtensions.operator_plus(expr, "]");
              expr = _operator_plus_7;
              boolean _hasNext_1 = iterX.hasNext();
              if (_hasNext_1) {
                String _operator_plus_8 = StringExtensions.operator_plus(expr, ", ");
                expr = _operator_plus_8;
              }
            }
            boolean _hasNext_2 = iterX.hasNext();
            _xwhileexpression = _hasNext_2;
          }
        }
      }
      String _operator_plus_9 = StringExtensions.operator_plus(expr, ")");
      expr = _operator_plus_9;
      return expr;
    }
  }
  
  public String generateFor(final For f) {
    {
      String expr = "";
      ForAll _all = f.getAll();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_all, null);
      if (_operator_notEquals) {
        {
          ForAll _all_1 = f.getAll();
          ScalarVariable _variable = _all_1.getVariable();
          String _generateVariable = this.generateVariable(_variable);
          String _operator_plus = StringExtensions.operator_plus("for ", _generateVariable);
          String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, " in range(");
          expr = _operator_plus_1;
          ForAll _all_2 = f.getAll();
          NumericFunctionExpression _start = _all_2.getStart();
          Object _generateNumericFunctionExpression = this.generateNumericFunctionExpression(_start);
          String _operator_plus_2 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression);
          String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, ", ");
          expr = _operator_plus_3;
          ForAll _all_3 = f.getAll();
          NumericFunctionExpression _end = _all_3.getEnd();
          Object _generateNumericFunctionExpression_1 = this.generateNumericFunctionExpression(_end);
          String _operator_plus_4 = StringExtensions.operator_plus(expr, _generateNumericFunctionExpression_1);
          String _operator_plus_5 = StringExtensions.operator_plus(_operator_plus_4, "):\n");
          expr = _operator_plus_5;
          ForAll _all_4 = f.getAll();
          EList<Statement> _statements = _all_4.getStatements();
          String _generateStatements = this.generateStatements(_statements);
          String statements = _generateStatements;
          String _replaceAll = statements.replaceAll("\n", "\n\t");
          String _operator_plus_6 = StringExtensions.operator_plus("\t", _replaceAll);
          statements = _operator_plus_6;
          String _operator_plus_7 = StringExtensions.operator_plus(expr, statements);
          expr = _operator_plus_7;
        }
      } else {
        ForJava _java = f.getJava();
        boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_java, null);
        if (_operator_notEquals_1) {
          {
            ForJava _java_1 = f.getJava();
            Variable _initialization = _java_1.getInitialization();
            String _generateVariable_1 = this.generateVariable(_initialization);
            String _operator_plus_8 = StringExtensions.operator_plus(_generateVariable_1, " = ");
            ForJava _java_2 = f.getJava();
            AssignmentRightHand _assignment = _java_2.getAssignment();
            Object _generateAssignmentRightHand = this.generateAssignmentRightHand(_assignment);
            String _operator_plus_9 = StringExtensions.operator_plus(_operator_plus_8, _generateAssignmentRightHand);
            String _operator_plus_10 = StringExtensions.operator_plus(_operator_plus_9, "\n");
            expr = _operator_plus_10;
            String _operator_plus_11 = StringExtensions.operator_plus(expr, "while ");
            ForJava _java_3 = f.getJava();
            Variable _condition = _java_3.getCondition();
            String _generateVariable_2 = this.generateVariable(_condition);
            String _operator_plus_12 = StringExtensions.operator_plus(_operator_plus_11, _generateVariable_2);
            String _operator_plus_13 = StringExtensions.operator_plus(_operator_plus_12, " ");
            ForJava _java_4 = f.getJava();
            String _comparison = _java_4.getComparison();
            String _operator_plus_14 = StringExtensions.operator_plus(_operator_plus_13, _comparison);
            String _operator_plus_15 = StringExtensions.operator_plus(_operator_plus_14, " ");
            ForJava _java_5 = f.getJava();
            NumericFunctionExpression _expression = _java_5.getExpression();
            Object _generateNumericFunctionExpression_2 = this.generateNumericFunctionExpression(_expression);
            String _operator_plus_16 = StringExtensions.operator_plus(_operator_plus_15, _generateNumericFunctionExpression_2);
            String _operator_plus_17 = StringExtensions.operator_plus(_operator_plus_16, ":\n");
            expr = _operator_plus_17;
            ForJava _java_6 = f.getJava();
            EList<Statement> _statements_1 = _java_6.getStatements();
            String _generateStatements_1 = this.generateStatements(_statements_1);
            String statements_1 = _generateStatements_1;
            String _replaceAll_1 = statements_1.replaceAll("\n", "\n\t");
            String _operator_plus_18 = StringExtensions.operator_plus("\t", _replaceAll_1);
            statements_1 = _operator_plus_18;
            ForJava _java_7 = f.getJava();
            Variable _variable_1 = _java_7.getVariable();
            String _generateVariable_3 = this.generateVariable(_variable_1);
            String _operator_plus_19 = StringExtensions.operator_plus(statements_1, _generateVariable_3);
            String _operator_plus_20 = StringExtensions.operator_plus(_operator_plus_19, " ");
            ForJava _java_8 = f.getJava();
            String _operation = _java_8.getOperation();
            String _operator_plus_21 = StringExtensions.operator_plus(_operator_plus_20, _operation);
            String _operator_plus_22 = StringExtensions.operator_plus(_operator_plus_21, " ");
            ForJava _java_9 = f.getJava();
            int _step = _java_9.getStep();
            String _string = ((Integer)_step).toString();
            String _operator_plus_23 = StringExtensions.operator_plus(_operator_plus_22, _string);
            String _operator_plus_24 = StringExtensions.operator_plus(_operator_plus_23, "\n");
            statements_1 = _operator_plus_24;
            String _operator_plus_25 = StringExtensions.operator_plus(expr, statements_1);
            expr = _operator_plus_25;
          }
        } else {
          ForWhile _forWhile = f.getForWhile();
          boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_forWhile, null);
          if (_operator_notEquals_2) {
            {
              ForWhile _forWhile_1 = f.getForWhile();
              VectorialVariable _variable_2 = _forWhile_1.getVariable();
              String _generateVariable_4 = this.generateVariable(_variable_2);
              String _operator_plus_26 = StringExtensions.operator_plus("while ", _generateVariable_4);
              String _operator_plus_27 = StringExtensions.operator_plus(_operator_plus_26, ".hasStuff():\n");
              expr = _operator_plus_27;
              ForWhile _forWhile_2 = f.getForWhile();
              EList<Statement> _statements_2 = _forWhile_2.getStatements();
              String _generateStatements_2 = this.generateStatements(_statements_2);
              String statements_2 = _generateStatements_2;
              String _replaceAll_2 = statements_2.replaceAll("\n", "\n\t");
              String _operator_plus_28 = StringExtensions.operator_plus("\t", _replaceAll_2);
              statements_2 = _operator_plus_28;
              String _operator_plus_29 = StringExtensions.operator_plus(expr, statements_2);
              expr = _operator_plus_29;
            }
          } else {
            ForFile _file = f.getFile();
            boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_file, null);
            if (_operator_notEquals_3) {
              {
                ForFile _file_1 = f.getFile();
                ScalarVariable _name = _file_1.getName();
                String _generateVariable_5 = this.generateVariable(_name);
                String _operator_plus_30 = StringExtensions.operator_plus("for ", _generateVariable_5);
                String _operator_plus_31 = StringExtensions.operator_plus(_operator_plus_30, " in listfiles(");
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("\"");
                ForFile _file_2 = f.getFile();
                String _path = _file_2.getPath();
                _builder.append(_path, "");
                _builder.append("\"");
                String _operator_plus_32 = StringExtensions.operator_plus(_operator_plus_31, _builder);
                String _operator_plus_33 = StringExtensions.operator_plus(_operator_plus_32, "):\n");
                expr = _operator_plus_33;
                ForFile _file_3 = f.getFile();
                EList<Statement> _statements_3 = _file_3.getStatements();
                String _generateStatements_3 = this.generateStatements(_statements_3);
                String statements_3 = _generateStatements_3;
                String _replaceAll_3 = statements_3.replaceAll("\n", "\n\t");
                String _operator_plus_34 = StringExtensions.operator_plus("\t", _replaceAll_3);
                statements_3 = _operator_plus_34;
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("\"");
                ForFile _file_4 = f.getFile();
                String _path_1 = _file_4.getPath();
                _builder_1.append(_path_1, "");
                _builder_1.append("\"");
                String _operator_plus_35 = StringExtensions.operator_plus("Partition(joinpath(", _builder_1);
                String _operator_plus_36 = StringExtensions.operator_plus(_operator_plus_35, ",");
                ForFile _file_5 = f.getFile();
                ScalarVariable _name_1 = _file_5.getName();
                String _generateVariable_6 = this.generateVariable(_name_1);
                String _operator_plus_37 = StringExtensions.operator_plus(_operator_plus_36, _generateVariable_6);
                String _operator_plus_38 = StringExtensions.operator_plus(_operator_plus_37, "))");
                String joinPath = _operator_plus_38;
                ForFile _file_6 = f.getFile();
                ScalarVariable _name_2 = _file_6.getName();
                String _generateVariable_7 = this.generateVariable(_name_2);
                String _replaceAll_4 = statements_3.replaceAll(_generateVariable_7, joinPath);
                statements_3 = _replaceAll_4;
                String _operator_plus_39 = StringExtensions.operator_plus(expr, statements_3);
                expr = _operator_plus_39;
              }
            }
          }
        }
      }
      return expr;
    }
  }
  
  public StringConcatenation generateAwesomePythonFramework() {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("from sys import exit");
    _builder.newLine();
    _builder.append("from os import listdir");
    _builder.newLine();
    _builder.append("from sys import argv, exit");
    _builder.newLine();
    _builder.append("from math import factorial, pow");
    _builder.newLine();
    _builder.append("from collections import defaultdict");
    _builder.newLine();
    _builder.append("from os.path import join, basename");
    _builder.newLine();
    _builder.append("from getpass import getuser");
    _builder.newLine();
    _builder.newLine();
    _builder.append("INT = 0");
    _builder.newLine();
    _builder.append("REAL = 1");
    _builder.newLine();
    _builder.append("PARTITION = 2");
    _builder.newLine();
    _builder.newLine();
    _builder.append("PATH = \"\"");
    _builder.newLine();
    _builder.append("        ");
    _builder.newLine();
    _builder.append("def binomial(a, b):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("return 0 if b > a else factorial(a) / (factorial(b) * factorial(a - b))");
    _builder.newLine();
    _builder.newLine();
    _builder.append("class Partition:");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __init__(self, filename):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self._filename = join(PATH, filename)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self.partition = None");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("try:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("f = open(self._filename, \"r\")");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("except IOError:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("print \"Could not open file \\\"%s\\\"\" % self._filename");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("exit(1)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("else:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("self.partition = defaultdict(list)");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("for v, k in [tuple(s.split()) for s in f.readlines()]:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("self.partition[k].append(v)    ");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("f.close()");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def calcCR(self, other):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("if self.partition is None or other is None:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("return 0.0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("top = bottom = 0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("totalSum = sumA = sumB = 0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("lastPart = 0");
    _builder.newLine();
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for clusterA in self.partition.values():");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("sumA += binomial(len(clusterA), 2)");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("sumB = 0");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("for clusterB in other.partition.values():");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("sumB += binomial(len(clusterB), 2)");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("elementsInBoth = sum([clusterB.count(obj) for obj in clusterA])");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("totalSum += binomial(elementsInBoth, 2)");
    _builder.newLine();
    _builder.newLine();
    _builder.append("        ");
    _builder.append("elementsInA = sum([len(l) for l in self.partition.values()])");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("lastPart = pow(binomial(elementsInA, 2), -1) * sumA * sumB");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("top = totalSum - lastPart");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("bottom = ((sumA + sumB)/2) - lastPart");
    _builder.newLine();
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return top/bottom");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __str__(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return basename(self._filename)");
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    _builder.append("class Array(list):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __init__(self, width, type_=None):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self._width = width");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self.type_ = type_");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("[self.append(None) for x in range(width)]");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def from_list(self, list_):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for i in range(len(list_)):");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("self[i] = list_[i]");
    _builder.newLine();
    _builder.append("            ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def size(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return len([x for x in self if x is not None])");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def add(self, *args):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("i = 0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for p in range(self._width):");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if i == len(args):");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("break");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if self[p] is None:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("self[p] = args[i]");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("i += 1");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return i");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def delete(self, *args):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for (x,) in args:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("try:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("self[x] = None");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("except IndexError:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("pass");
    _builder.newLine();
    _builder.append("            ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def hasStuff(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for x in self:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if x is not None:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("return True");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return False");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def mean(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("sum_ = 0.0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("count = 0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for a in self:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if type(a) in (float, int):");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("sum_ += a");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("count += 1");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return sum_ / count");
    _builder.newLine();
    _builder.append("                  ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def indexOfMax(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return self.index(max(self))");
    _builder.newLine();
    _builder.append("        ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __str__(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("fmt = lambda x: str(x)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("if self.type_ == REAL:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("fmt = lambda x: \"%.4f\" % x");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return \"\\t\".join([fmt(v) if v is not None else \"-\" for v in self]) + \"\\n\"");
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    _builder.append("class Matrix(list):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __init__(self, width, height, type_=None):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self._width = width");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self._height = height");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("self.type_ = type_");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("[self.append(Array(self._width, self.type_)) for x in range(self._height)]");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def size(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return sum([a.size() for a in self])");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def add(self, *args):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("i = 0");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for p in range(self._height):");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("i += self[p].add(*args[i:])");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return i");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def delete(self, *args):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for (x, y) in args:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("self[x].delete((y,))");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def hasStuff(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for a in self:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if a.hasStuff():");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("return True");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return False");
    _builder.newLine();
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def mean(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("a = Array(self._height, REAL)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("a.from_list([x.mean() for x in self])");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return a");
    _builder.newLine();
    _builder.append("                ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("def __str__(self):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return \"\".join([str(a) for a in self])");
    _builder.newLine();
    _builder.append("        ");
    _builder.newLine();
    _builder.append("def print_(*args):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("for arg in args:");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("print arg,");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("def highestCR(array):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("return array.indexOfMax()");
    _builder.newLine();
    _builder.newLine();
    _builder.append("def calcMean(iterable):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("return iterable.mean()");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("def findSimilar(matrix, index, threshold):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("indexes = []");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("line = matrix[index]");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("for i in range(len(line)):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("if line[i] >= threshold:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("indexes.append([index, i])");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("return indexes");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("def listfiles(dir_):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("try:");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return listdir(join(PATH, dir_))");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("except:");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("print \"Could not list directory \" + dir_");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("exit(1)");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("def joinpath(p, f):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("return join(p, f)");
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    _builder.append("def calcCR(a, b=None):");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("if isinstance(a, Partition) and isinstance(b, Partition):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return a.calcCR(b)");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("elif isinstance(a, Partition) and isinstance(b, Array):");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("calc = Array(len(b), REAL)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for p in b:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if p is not None:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("calc.add(a.calcCR(p))");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return calc");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("elif b is None:");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("calc = Matrix(len(a), len(a), REAL)");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("for p in a:");
    _builder.newLine();
    _builder.append("            ");
    _builder.append("if p is not None:");
    _builder.newLine();
    _builder.append("                ");
    _builder.append("calc.add(*calcCR(p, a))");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return calc");
    _builder.newLine();
    return _builder;
  }
}